﻿using Application.Common.Interfaces;
using Common.Events;
using Common.Helpers;
using Common.Services;
using Domain.Entities;
using Domain.Entities.Identity;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Domain.Services;
using Common.Utils;
using Application.Features.Menus.DTOs;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Http;
using Common.Caching;

namespace Application.Features.Auth.EventHandlers;

#nullable disable
public class RegisterEventHandler : INotificationHandler<CreatedEvent<User>>
{
    private readonly ILogger<RegisterEventHandler> _logger;
    private readonly IServiceProvider _serviceProvider;
    private readonly ISnowFlakeService _snowFlakeService;
    private readonly MenuDomainService _menuDomainService;
    private readonly IMapper _mapper;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ICacheService  _cacheService;

    public RegisterEventHandler(
        ILogger<RegisterEventHandler> logger,
        IServiceProvider serviceProvider,
        ISnowFlakeService snowFlakeService,
        MenuDomainService menuDomainService,
        IMapper mapper,
        IHttpContextAccessor httpContextAccessor,
        ICacheService cacheService)
    {
        _logger = logger;
        _serviceProvider = serviceProvider;
        _snowFlakeService = snowFlakeService;
        _menuDomainService = menuDomainService;
        _mapper = mapper;
        _httpContextAccessor = httpContextAccessor;
        _cacheService = cacheService;
    }

    public async Task Handle(CreatedEvent<User> notification, CancellationToken cancellationToken)
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            var _context = scope.ServiceProvider.GetRequiredService<IApplicationDbContext>();
            if (_context.Users.Count() > 1) return;
            try
            {
                _context.Database.BeginTransaction();

                var transactionId = _context.Database.CurrentTransaction.TransactionId.ToString();
                Console.WriteLine($"数据库事务ID1：{transactionId}");

                var systemSuperAdmin = await _context.Users.SingleOrDefaultAsync(x => x.Id == notification.Entity.Id && x.IsSystemAccount != true);

                systemSuperAdmin.IsSystemAccount = true;
                systemSuperAdmin.IsActived(true);
                _context.Users.Update(systemSuperAdmin);
                await _context.SaveChangesAsync();

                var systemSuperRole = new Role()
                {
                    Id = _snowFlakeService.GenerateId(),
                    IsActive = true,
                    RoleName = "系统超级管理员",
                    Description = "系统中拥有至高无上的权限",
                    RoleCode = "admin",
                    Sort = 0
                };
                _context.Roles.Add(systemSuperRole);
                await _context.SaveChangesAsync();

                var systemSuperAdminRole = new UserRole()
                {
                    Id = _snowFlakeService.GenerateId(),
                    RoleId = systemSuperRole.Id,
                    UserId = systemSuperAdmin.Id,
                };
                _context.UserRoles.Add(systemSuperAdminRole);
                await _context.SaveChangesAsync();

                var menus = new List<Menu>();
                try
                {
                    var saveFilePath = Path.Combine(Directory.GetCurrentDirectory(), "menus.json");
                    if (File.Exists(saveFilePath))
                    {
                        var menusJson = File.ReadAllText(saveFilePath);
                        var backupMenus = menusJson.FromJson<IEnumerable<BackupMenuOutput>>();
                        if (!backupMenus.Any())
                        {
                            throw new InvalidOperationException("备份菜单数据为空");
                        }
                        menus = _mapper.Map<List<Menu>>(backupMenus);
                    }
                    else
                    {
                        var controllerInfos = WebApiDocHelper.GetWebApiControllersWithActions();
                        menus = _menuDomainService.WebAPIEndpointCollectionForMenu().ToList();
                    }
                }
                catch (Exception)
                {
                    var controllerInfos = WebApiDocHelper.GetWebApiControllersWithActions();
                    menus = _menuDomainService.WebAPIEndpointCollectionForMenu().ToList();
                }
                finally
                {
                    _context.Menus.AddRange(menus);
                    await _context.SaveChangesAsync();
                }

                var roleMenus = new List<RoleMenu>();
                var allMenus = _context.Menus.ToList();
                foreach (var menu in allMenus)
                {
                    var roleMenu = new RoleMenu()
                    {
                        Id = _snowFlakeService.GenerateId(),
                        RoleId = systemSuperRole.Id,
                        MenuId = menu.Id
                    };
                    roleMenus.Add(roleMenu);
                }
                _context.RoleMenus.AddRange(roleMenus);
                await _context.SaveChangesAsync();

                _context.Database.CommitTransaction();
                _logger.LogDebug($"{nameof(RegisterEventHandler)}；创建系统超级管理员成功");
            }
            catch (Exception ex)
            {
                _logger.LogDebug($"{nameof(RegisterEventHandler)}；创建系统超级管理员失败：{ex.Message}");
                _context.Database.RollbackTransaction();
            }
        }
    }
}